/*
 *   Copyright (C) 2016 by P. Sereno
 *   http://www.qt-italia.net
 */

#include <QColor>
#include <QtGlobal>
#include <QtGui>
#include <QPolygon>
#include <QtMath>
#include "steernewmeter.h"
#include <QPainter>


void SteerNewMeter::drawCrown(QPainter *painter)
{
    painter->save();
    QRectF rectangle(-47, -47, 94, 94);
    int startAngle = 30 * 16;
    int spanAngle = 390 * 16;
    QLinearGradient linearGrad(QPointF(-47, -47), QPointF(94, 94));
    linearGrad.setColorAt(0, Qt::white);
    linearGrad.setColorAt(0.3, QColor(60,60,60,250));
    QPen pen;
    QBrush brush=QBrush(linearGrad);
    pen.setBrush(brush);
    pen.setWidth(3);
    painter->setPen(pen);
    painter->drawArc(rectangle, startAngle, spanAngle);
    painter->restore();
}

void SteerNewMeter::drawBackground(QPainter *painter)
{
    painter->setBrush(m_background);
    painter->drawEllipse(-45, -45, 90, 90);
}

void SteerNewMeter::drawTicks(QPainter *painter)
{
    painter->save();
    QPen pen=QPen(m_foreground);
    pen.setWidth(0);
    painter->setPen(pen);
    int nSteps=m_steps;
    painter->rotate(-m_startAngle) ;
    double angleStep=(-m_endAngle+m_startAngle)/m_steps;
    for ( int i=0; i<=nSteps;i++ )
    {
        painter->drawLine(28,0,30,0 );
        painter->rotate( angleStep/1 );
    }
    painter->restore();

    pen.setWidth(0);
    painter->setPen(pen);
    double spanAngle=m_endAngle-m_startAngle;
    painter->drawArc(-28,-28,56,56, m_startAngle*16, spanAngle*16);
}


void SteerNewMeter::drawScale(QPainter *painter)
{
    painter->save();
    painter->setPen(m_foreground);

    double startRad=m_startAngle*M_PI/180.0;
    startRad+=M_PI/2;
    double deltaRad=(m_endAngle-m_startAngle)/(m_steps)*(M_PI/180);
    double sina,cosa;
    for ( int i=0; i<=m_steps; i++ )
    {
        sina=sin((double)(startRad+i*deltaRad));
        cosa=cos((double)(startRad+i*deltaRad));
        double tmpVal=i*((m_maxValue-m_minValue)/m_steps);
        tmpVal+=m_minValue;
        QString str = QString( "%1" ).arg(tmpVal,0,'f',m_precision);
        if(_customTextList.size()>0){
            str = _customTextList.at(str.toInt());
        }
        QFontMetricsF fm( this->font() );
        double w=fm.size(Qt::TextSingleLine,str).width();
        double h=fm.size(Qt::TextSingleLine,str).height();
        int x=(int)((38*sina)-(w/2));
        int y=(int)((38*cosa)+(h/4));
        painter->drawText(x,y,str);
    }
    painter->restore();
}

void SteerNewMeter::drawUnits(QPainter *painter)
{
    painter->setPen(m_foreground);
    painter->setBrush(m_foreground);
    painter->setPen(m_foreground);
    QRectF labelRect=QRectF(-15,-20,30,10);
    painter->drawText(labelRect,Qt::AlignCenter, m_units);
}

void SteerNewMeter::drawNumericValue(QPainter *painter)
{
    if(!enableNumericIndicator())
        return;
    painter->save();
    //--------------
    QString str = "";
    if(_customTextList.size()>0){
        str = _customTextList.at(m_value);
    }
    if(!_valueText.isEmpty()){
        str = _valueText;
    }else if(_customTextList.size()>0){
        str = _customTextList.at(m_value);
    }else{
        str =  QString( "%1" ).arg(m_value,0,'f',m_precisionNumeric);
    }

    //QColor color;

    // if(!m_thresholdFlag)
    //     color = QColor(0,170,255);
    // else
    //     color = Qt::red;
    QRectF labelRect=QRectF(-28,16,56,15);
    //    QRectF labelRect=QRectF(0,15,this->width(),20);
    painter->setPen(QColor(61,61,61));
    //    painter->fillRect(labelRect,Qt::red);
    QFont font("Microsoft YaHei", 9, QFont::Thin);
    font.setBold(false);
    painter->setFont(font);
    painter->drawText(labelRect,Qt::AlignCenter, str);
    painter->restore();
}

void SteerNewMeter::drawNeedle(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QColor(26,26,26));
    painter->drawEllipse(-8, -8, 16, 16);

    QPen pen;
    pen.setWidth(1);
    pen.setColor(QColor(93,93,93));
    painter->setPen(pen);
    painter->setBrush(Qt::NoBrush);
    painter->drawEllipse(-6, -6, 12, 12);
    painter->restore();

    // 绘制指针主体
    painter->save();
    painter->rotate(-90.0); // 初始旋转调整

    QPolygon pts;
    pts.setPoints(3, -1,0, 1,0, 0,26);

    QPolygon shadow;
    shadow.setPoints(3, -1,0, 1,0, 0,24);

    int degRotate = (int)(m_startAngle + (m_endAngle - m_startAngle) /
                                              (m_maxValue - m_minValue) * (m_value - m_minValue));

    painter->rotate(-degRotate);

    QRadialGradient haloGradient(0, 0, 25, 0, 0);
    haloGradient.setColorAt(0.0, QColor(232,236,244));
    haloGradient.setColorAt(1.0, QColor(30,30,31));


    QPen needlePen(QColor(30,30,31), 1); // 指针轮廓颜色
    painter->setPen(needlePen);
    painter->setBrush(haloGradient);
    painter->drawConvexPolygon(pts);

    // 绘制针尖圆帽（使针尖更圆润）
    painter->setBrush(QColor(232,236,244));
    painter->drawEllipse(QPointF(0, 0), 1.5, 1.5); // 针头圆帽

    // 绘制高光阴影
    painter->setPen(Qt::NoPen);
    painter->setBrush(QColor(232,236,244));
    painter->drawConvexPolygon(shadow);

    painter->restore();

    // draw needle hat
    // QLinearGradient linearGrad(QPointF(-7, -7), QPointF(14, 14));
    // linearGrad.setColorAt(0, Qt::white);
    // linearGrad.setColorAt(1, Qt::black);
}

void SteerNewMeter::drawThresholdLine(QPainter *painter)
{
    if (!enableThreshold())
        return;

    painter->save();

    // Calculate the threshold angle
    double thresholdAngle = (m_startAngle + (m_endAngle - m_startAngle) / (m_maxValue - m_minValue) * (m_threshold - m_minValue));

    const double outerRadius = 25;          // 外环半径（填充部分）
    const double ringWidth = 5;             // 圆环填充宽度 5px
    const double innerRadius = outerRadius - ringWidth;  // 内环半径（填充部分）

    const double shellPadding = 1;        // 外壳轮廓线向外延伸 1.5px
    const double shellOuterRadius = outerRadius + shellPadding;  // 外壳外半径
    const double shellInnerRadius = 19;                 // 外壳内半径（与填充外环对齐）

    // 1. 绘制填充部分（蓝色 + 青色，宽度 5px）
    QRectF fillOuterRect(-outerRadius, -outerRadius, 2 * outerRadius, 2 * outerRadius);
    QRectF fillInnerRect(-innerRadius, -innerRadius, 2 * innerRadius, 2 * innerRadius);

    // 左侧填充（蓝色）
    QPainterPath leftFillPath;
    leftFillPath.arcMoveTo(fillOuterRect, m_startAngle);
    leftFillPath.arcTo(fillOuterRect, m_startAngle, thresholdAngle - m_startAngle);
    leftFillPath.arcTo(fillInnerRect, thresholdAngle, -(thresholdAngle - m_startAngle));
    leftFillPath.closeSubpath();

    // 右侧填充（青色）
    QPainterPath rightFillPath;
    rightFillPath.arcMoveTo(fillOuterRect, thresholdAngle);
    rightFillPath.arcTo(fillOuterRect, thresholdAngle, m_endAngle - thresholdAngle);
    rightFillPath.arcTo(fillInnerRect, m_endAngle, -(m_endAngle - thresholdAngle));
    rightFillPath.closeSubpath();

    painter->setPen(Qt::NoPen);
    painter->setBrush(QColor(95, 148, 254)); // 蓝色
    painter->drawPath(leftFillPath);
    painter->setBrush(QColor(46, 233, 248)); // 青色
    painter->drawPath(rightFillPath);

    // 2. 绘制外壳轮廓线（在填充部分之外）
    QRectF shellOuterRect(-shellOuterRadius, -shellOuterRadius, 2 * shellOuterRadius, 2 * shellOuterRadius);
    QRectF shellInnerRect(-shellInnerRadius, -shellInnerRadius, 2 * shellInnerRadius, 2 * shellInnerRadius);

    QPainterPath shellPath;
    shellPath.arcMoveTo(shellOuterRect, m_startAngle);
    shellPath.arcTo(shellOuterRect, m_startAngle, m_endAngle - m_startAngle);
    shellPath.arcTo(shellInnerRect, m_endAngle, -(m_endAngle - m_startAngle));
    shellPath.closeSubpath();

    QPen shellPen(QColor(220, 226, 238), shellPadding, Qt::SolidLine, Qt::RoundCap);
    painter->setPen(shellPen);
    painter->setBrush(Qt::NoBrush);
    painter->drawPath(shellPath);

    painter->restore();
}

void SteerNewMeter::drawCoverGlass(QPainter *painter)
{
    painter->save();
    QLinearGradient linearGrad(QPointF(-15, -45), QPointF(90, 75));
    linearGrad.setColorAt(0, QColor(255,255,255,30));
    linearGrad.setColorAt(0.3, QColor(120,120,120,20));
    QBrush brush=QBrush(linearGrad);
    QPen pen;
    pen = QColor(0,0,0,0);
    pen.setBrush(brush);
    pen.setWidth(0);
    painter->setPen(pen);
    painter->setBrush(brush);
    painter->drawEllipse(-45,-45,90,90);
    painter->restore();
}

void SteerNewMeter::drawLabel(QPainter *painter)
{
    painter->save();
    painter->setPen(m_foreground);
    painter->setBrush(m_foreground);
    painter->setPen(m_foreground);

    QFontMetricsF fm( this->font() );
    double w=fm.size(Qt::TextSingleLine,m_label).width();

    QRectF labelRect=QRectF(-20,15,40,10);

    if(w>labelRect.width())
    {
        QFont font = painter->font();
        int pointSize=font.pointSize();
        pointSize--;
        font.setPointSize(pointSize);
        setFont(font);
    }

    painter->drawText(labelRect,Qt::AlignCenter, m_label);
    painter->restore();
}

void SteerNewMeter::drawWarningWindow(QPainter *painter)
{
    if(enableWarningWindow())
    {

        QPen pen;

        double beginAngle = ( m_startAngle+(m_endAngle-m_startAngle)/(m_maxValue-m_minValue)*(m_beginWarningValue-m_minValue) );
        double endAngle =( m_startAngle+(m_endAngle-m_startAngle)/(m_maxValue-m_minValue)*(m_endWarningValue-m_minValue) );

        pen.setWidth(2);

        pen.setColor(Qt::yellow);
        painter->setPen(pen);
        if(beginAngle>endAngle)
            painter->drawArc(-25,-25,50,50,(int)endAngle*16,(int)(beginAngle-endAngle)*16);
        else
            painter->drawArc(-25,-25,50,50,(int)beginAngle*16,(int)(endAngle-beginAngle)*16);
    }
}

void SteerNewMeter::drawValidWindow(QPainter *painter)
{
    if(enableValidWindow())
    {
        QPen pen;

        double beginAngle = ( m_startAngle+(m_endAngle-m_startAngle)/(m_maxValue-m_minValue)*(m_beginValidValue-m_minValue) );
        double endAngle =( m_startAngle+(m_endAngle-m_startAngle)/(m_maxValue-m_minValue)*(m_endValidValue-m_minValue) );

        pen.setWidth(2);

        pen.setColor(Qt::green);
        painter->setPen(pen);
        if(beginAngle>endAngle)
            painter->drawArc(-25,-25,50,50,(int)endAngle*16,(int)(beginAngle-endAngle)*16);
        else
            painter->drawArc(-25,-25,50,50,(int)beginAngle*16,(int)(endAngle-beginAngle)*16);
    }
}

